#ifndef ABCKIT_METADATA_H
#define ABCKIT_METADATA_H

#include "c/abckit.h"
#include <vector>
#include <set>
#include <memory>

namespace abc
{

    enum class AbckitVersion
    {
        V1,
        V2,
        LATEST = V1 // 默认使用V1版本
    };

    enum class AbcNodeType
    {
        MODULE,
        NAMESPACE,
        CLASS,
        FUNCTION,
        UNKOWN
    };

    using CoreNode = std::variant<
        AbckitCoreModule *,
        AbckitCoreNamespace *,
        AbckitCoreClass *,
        AbckitCoreFunction *>;

    enum class AbcFuncType
    {
        NORMAL,
        CONSTRUCTOR,
        GETTER,
        SETTER,
        METHOD,
        LAMBDA,
        MAIN,
        BUILD,
        LIFECYCLE,
        OTHER
    };

    struct ImportDescriptor
    {
        AbckitCoreImportDescriptor *i;
        std::string importName;
        AbckitCoreModule *importedModule;
    };

    struct Path
    {
        std::string module;
        std::string package;
        std::vector<std::string> namespaces;
        std::string originModulePath;

        // std::string toString() const;
    };

    class AbcFunction;
    class AbcNode;

    using AbcFunctionPtr = std::shared_ptr<AbcFunction>;
    using AbcNodePtr = std::shared_ptr<AbcNode>;

    class AbcFunction
    {
    public:
        std::string name;
        AbckitCoreFunction *coreFunction = nullptr;
        AbcFuncType type = AbcFuncType::NORMAL;
        Path path;

        bool isTopLevel = false;
        bool hasAnno = false;
        bool isStatic = false;

        AbcNodePtr parentNode;
        std::set<AbcFunctionPtr> lambdas;
    };

    class AbcNode
    {
    public:
        AbcNodeType type;
        std::string name;
        Path path;
        CoreNode coreNode;

        AbcNodePtr parentNode;
        std::vector<AbcFunctionPtr> functions;

        template <typename T>
        T *getAs() const
        {
            return std::get_if<T>(&coreNode);
        }

        bool isModule() const { return type == AbcNodeType::MODULE; }
        bool isNamespace() const { return type == AbcNodeType::NAMESPACE; }
        bool isClass() const { return type == AbcNodeType::CLASS; }
    };

    struct AbcFunctionPtrComparator
    {
        bool operator()(const AbcFunctionPtr &lhs, const AbcFunctionPtr &rhs) const
        {
            if (!lhs && !rhs)
                return false;
            if (!lhs)
                return true;
            if (!rhs)
                return false;
            // 实现你的比较逻辑，例如按函数名比较
            return lhs->name < rhs->name;
        }
    };

}

#endif